#include "I_BaseLib.h"

SKYPE_CL::SKYPE_CL(HWND hWnd)
{
	SkypeLog("---------------NEW LOG STARTED-------------");
	msgSkypeControlAPIAttach=RegisterWindowMessage(L"SkypeControlAPIAttach");
	msgSkypeControlAPIDiscover=RegisterWindowMessage(L"SkypeControlAPIDiscover");
	if( msgSkypeControlAPIAttach!=0 && msgSkypeControlAPIDiscover!=0 )
	{
		OwnHWND = hWnd;
		SkypeHWND = NULL;
		SkypeLog("Register Windows Message ok");
		if (ReadAllowedList()) SkypeLog("Allowed user list loaded!");// PrintAllowedUsers();}
		else {SkypeLog("Allowed user list NOT loaded, EXITING!"); exit(0);}
		SendMessage( HWND_BROADCAST, msgSkypeControlAPIDiscover, (WPARAM)OwnHWND, 0);
	}
	else SkypeLog("Register Windows Message failed, Skype_CL _not_ constructed");

}

SKYPE_CL::~SKYPE_CL()
{
	if (logfile.is_open()) logfile.close();
}

bool SKYPE_CL::ConnectionKeepAlive()
{
	if (!SkypeConnected()) SendMessage( HWND_BROADCAST, msgSkypeControlAPIDiscover, (WPARAM)OwnHWND, 0);
	return true;
}

bool SKYPE_CL::ReadAllowedList()
{
	std::ifstream allowed;
	allowed.open(L"allowed.txt");
	if (allowed.is_open())
	{
		allowedusers = *(new vector<string>((std::istream_iterator<string>(allowed)), std::istream_iterator<string>()));
		return true;
		allowed.close();
	}
	else return false;
}

void SKYPE_CL::PrintAllowedUsers()
{
	vector<string>::iterator vi;

	for ( vi = allowedusers.begin() ; vi < allowedusers.end() ; vi++)
	{
		SkypeLog( (*vi).c_str() );
	}
}

void SKYPE_CL::SkypeLog(const char*param)
{
	if (LOGGING){
	if (!logfile.is_open())
		logfile.open(L"SkypeLog.txt",ios::out | ios::app);
	
		logfile<<param<<endl;
		logfile.close();
	}
}

LRESULT SKYPE_CL::MainMsgProc(UINT uiMessage, WPARAM wParam, LPARAM lParam)
{
	
	LRESULT returncode = 0;
	//TZapMainForm.UnicodeClass
	
	switch(uiMessage)
	{
	case WM_COPYDATA:
		if( SkypeHWND==(HWND)wParam )
		{
			PCOPYDATASTRUCT poCopyData=(PCOPYDATASTRUCT)lParam;
			ParseMsg((const char *)poCopyData->lpData);
			returncode = 1;
		}
		break;
	default:
		if( uiMessage==msgSkypeControlAPIAttach ) //if skype answered!
		{
			switch(lParam)
			{
			case SKYPECONTROLAPI_ATTACH_SUCCESS:
				SkypeLog("!!! ATTACH_SUCCESS;");
				SkypeHWND=(HWND)wParam;
				break;
			case SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION:
				SkypeLog("!!! Pending authorization");
				break;
			case SKYPECONTROLAPI_ATTACH_REFUSED:
				SkypeLog("!!! Connection refused");
				break;
			case SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE:
				SkypeLog("!!! Skype API not available");
				break;
			case SKYPECONTROLAPI_ATTACH_API_AVAILABLE:
				SkypeLog("!!! Try connect now (API available);");
				SendMessage( HWND_BROADCAST, msgSkypeControlAPIDiscover, (WPARAM)OwnHWND, 0);
				break;
			}
			returncode=1;
			
		}
		break;
	}
	return returncode;
	
}

bool SKYPE_CL::SkypeConnected()
{
	return (SkypeHWND!=NULL);
}

void SKYPE_CL::SkypeDisconnect()
{
	SkypeHWND=NULL;
}
void SKYPE_CL::SendSkypeMessage (const char *command)
{
	if( SkypeConnected() )
	{
		COPYDATASTRUCT oCopyData;

		// send command to skype
		oCopyData.dwData=0;
		oCopyData.lpData=(void *)command;
		oCopyData.cbData=(DWORD) strlen(command)+1; //length of command
		if( oCopyData.cbData!=1 )
		{
			if( SendMessage( SkypeHWND, WM_COPYDATA, (WPARAM)OwnHWND, (LPARAM)&oCopyData)==FALSE )
			{
				SkypeDisconnect();
			}
		}
	}
}
void SKYPE_CL::ParseMsg(string command)
{

	SkypeLog(command.c_str());
	Process_Commands(command);
		
}

string SKYPE_CL::GetCommand(const string& mainstring)
{
	size_t pos = mainstring.find_first_of(' ');
	if (pos!=string::npos)
	{
		return mainstring.substr(0,pos);
	}
	return mainstring;
}

void SKYPE_CL::Split_at_char(vector<string>& substrings,const string& mainstring,char separator)
{
	
	size_t pos = mainstring.find_first_of(separator);
	if (pos!=string::npos)
	{
		substrings.push_back(mainstring.substr(0,pos));
		Split_at_char(substrings,mainstring.substr(pos+1,mainstring.length()),separator);
	}
	else
	{
		substrings.push_back(mainstring.substr(0,mainstring.length()));
	}
	
}


//leave the 4th parameters untouched!
void SKYPE_CL::Split_MSG_at_char(vector<string>& substrings,const string& mainstring,char separator,int depth)
{

	size_t pos = mainstring.find_first_of(separator);
	while ((depth<3) && (pos!=string::npos))
	{
		substrings.push_back(mainstring.substr(0,pos));
		depth++;
		Split_MSG_at_char(substrings,mainstring.substr(pos+1,mainstring.length()),separator,depth);
		
	}
	
		substrings.push_back(mainstring.substr(0,mainstring.length()));
	

}

void SKYPE_CL::Process_Commands(const string& mainstring)
{
	
	vector<string> substrings;
	std::ostringstream o;
	int msg_completed;
	
	if (GetCommand(mainstring).compare("CONNECTION")==0)
	{
		SkypeLog("CONNECTION!");
	}
	if (GetCommand(mainstring).compare("USERSTATUS")==0)
	{
		SkypeLog("USERSTATUS!");
	}
	if (GetCommand(mainstring).compare("CHAT")==0)
	{
		SkypeLog("CHAT INFO jott!");
		Split_at_char(substrings,mainstring,' ');
		chatlist.push_back(substrings[1]);
	}
	if (GetCommand(mainstring).compare("MESSAGE")==0)
	{
		SkypeLog("MESSAGE jott!");
		Split_MSG_at_char(substrings,mainstring,' ',0);
		if (substrings.size() > 3) //the right type of message
		{
			if (substrings[3].compare("RECEIVED")==0)
			{
				SkypeLog("!!!NA MOST KAPTUNK MESSAGET");
						
				//new message arrived
				msgContainer mc;
				messagequeue[atoi(substrings[1].c_str())] = mc;
				
				//get all the properties
				GetChatID(substrings[1]);
				GetMessageOwner(substrings[1]);
				GetMessageBody(substrings[1]);
				GetUser(substrings[1]);
			}

			if (substrings[2].compare("CHATNAME")==0)
			{
				SkypeLog("!!!!MEGJOTT A CHAT_ID");
				messagequeue[atoi(substrings[1].c_str())].chat_id = substrings[3];
			}

			if (substrings[2].compare("FROM_DISPNAME")==0)
			{
				SkypeLog("!!!!!MEGJOTT A Message OWNER");
				messagequeue[atoi(substrings[1].c_str())].message_owner = substrings[3];
			}
			
			if (substrings[2].compare("FROM_HANDLE")==0)
			{
				SkypeLog("!!!!!MEGJOTT A Message OWNER skype usere!");
				messagequeue[atoi(substrings[1].c_str())].user = substrings[3];
			}
			
			if (substrings[2].compare("BODY")==0)
			{
				SkypeLog("!!!!!!MEGJOTT A Message BODY");
				messagequeue[atoi(substrings[1].c_str())].message = substrings[3];
			}


			msg_completed = MessagesCompleted();
			if (msg_completed>0) 
			{
				if (UserIsAllowed(messagequeue[msg_completed].user))
				{
					o << messagequeue[msg_completed].chat_id;
					//string a = messagequeue[msg_completed].message_owner;
					//a += " ";
					string a = ProcessMessage(messagequeue[msg_completed].message);
					SendChatMessage(o.str(),a);
				}
					messagequeue.erase(msg_completed);
			}

		}
		
	}
	
}

bool SKYPE_CL::UserIsAllowed(string user)
{
	vector<string>::iterator vi;
	
	for ( vi = allowedusers.begin() ; vi < allowedusers.end() ; vi++)
	{
		if (user.compare(*vi) == 0) //we have a match
			 return true;
		else
		{
			string temp;
			temp = user;
			temp += " ";
			temp += *vi;
			SkypeLog(temp.c_str());
		}
	}
	return false;
}

void SKYPE_CL::SendChatMessage(const string& chat_id,const string& message)
{
	string a = "CHATMESSAGE";
	a += " ";
	a += chat_id;
	a += " ";
	a += message;
	SendSkypeMessage(a.c_str());
}

void SKYPE_CL::GetChatID(const string& message_id)
{
	string a = "GET CHATMESSAGE";
	a += " ";
	a += message_id;
	a += " ";
	a += "CHATNAME";
	SendSkypeMessage(a.c_str());
}

void SKYPE_CL::GetMessageOwner(const string& message_id)
{
	string a = "GET CHATMESSAGE";
	a += " ";
	a += message_id;
	a += " ";
	a += "FROM_DISPNAME";
	SendSkypeMessage(a.c_str());
}

void SKYPE_CL::GetUser(const string& message_id)
{
	string a = "GET CHATMESSAGE";
	a += " ";
	a += message_id;
	a += " ";
	a += "FROM_HANDLE";
	SendSkypeMessage(a.c_str());
}

void SKYPE_CL::GetMessageBody(const string& message_id)
{
	string a = "GET CHATMESSAGE";
	a += " ";
	a += message_id;
	a += " ";
	a += "BODY";
	SendSkypeMessage(a.c_str());
}

int SKYPE_CL::MessagesCompleted()
{
	for (map<int,msgContainer>::iterator i=messagequeue.begin();i!=messagequeue.end();i++)
	{
		if ((*i).second.is_complete()) return (*i).first;
	}
	return -1;
}

void SKYPE_CL::EscapeString(string& message)
{
	size_t pos;
	
	pos = message.find("'"); 
	while (pos!=string::npos)
	{
		message.replace(pos,1," ");
		pos=message.find("'",pos+1);
	}
	
	pos = message.find("\""); 
	while (pos!=string::npos)
	{
		message.replace(pos,1," ");
		pos=message.find("\"",pos+1);
	}
}

string SKYPE_CL::ProcessMessage(string& message)
{
	std::ifstream input;
	EscapeString(message);
	string script = "powershell.exe -command \"& .\\ai\\findAnswer.ps1 '";
	script += message;
	script += "'\" > output.txt";
	
	SkypeLog("___>> SCRIPT RUNNING!");

	system(script.c_str()); //executing shellscript (syncron)

	SkypeLog("___>> SCRIPT FINISHED!");
	input.open(L"output.txt");
	if (input.is_open())
	{
		string reply((std::istreambuf_iterator<char>(input)), std::istreambuf_iterator<char>());
		SkypeLog(reply.c_str());
		return reply;
		input.close();
	}
	else return "Sorry, no answer received!";

}